package validator

import (
	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/gin/log"
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	zhTranslations "github.com/go-playground/validator/v10/translations/zh"
	"reflect"
	"sync"
)

var ReqValidator *validator.Validate

func init() {
	ReqValidator = InitValidator()
}

// 替换gin的binding
func Init() {
	valid := new(DefaultValidator)
	binding.Validator = valid
}

type DefaultValidator struct {
	once     sync.Once
	validate *myValidator
}

var _ binding.StructValidator = &DefaultValidator{}

func (v *DefaultValidator) ValidateStruct(obj interface{}) error {

	if kindOfData(obj) == reflect.Struct {
		v.lazyinit()
		if err := v.validate.Validate(obj); err != nil {
			return err[0]
		}
	}

	return nil
}

func (v *DefaultValidator) Engine() interface{} {
	v.lazyinit()
	return v.validate
}

func (v *DefaultValidator) lazyinit() {
	v.once.Do(func() {
		v.validate = New()
		v.validate.SetTag("binding")
		v.validate.SetValidatorSplit("|")
		// add any custom validations etc. here
	})
}

func kindOfData(data interface{}) reflect.Kind {

	value := reflect.ValueOf(data)
	valueType := value.Kind()

	if valueType == reflect.Ptr {
		valueType = value.Elem().Kind()
	}
	return valueType
}

func InitValidator() *validator.Validate {
	// validator
	zhTranslator := zh.New()
	universalTranslator := ut.New(zhTranslator, zhTranslator)
	ReqValidator = validator.New()
	translator, findTrans := universalTranslator.GetTranslator("zh")
	if !findTrans {
		log.Error("translator not found")
	}
	if errRegTrans := zhTranslations.RegisterDefaultTranslations(ReqValidator, translator); errRegTrans != nil {
		log.Error(errRegTrans)
	}
	return ReqValidator
}
